import md5 from 'js-md5';

/**
 * 将base64编码转化为明文 - 防止传输的是utf-16格式 虽然后台返回的是utf8 但是解析的是utf16 出现中文乱码
 * @param str
 * @returns {string}
 */
const getDecodeBase64 = (str) => {
    return decodeURIComponent(atob(str).split('').map(function (c) {
        return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
    }).join(''));
}

/**
 * 将字符串转化为base64编码
 * @param str
 * @returns {string}
 */
 const getEncodeBase64 = (str) => {
     return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g,
         function toSolidBytes(match, p1) {
             return String.fromCharCode('0x' + p1);
         }));
 }

/**
 * 获取唯一标记符
 * @returns {string}
 */
const getUuid = () => {
    let s = [];
    const hexDigits = "0123456789abcdef";
    for (let i = 0; i < 36; i++) {
        s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
    }
    s[14] = "4"; // bits 12-15 of the time_hi_and_version field to 0010
    s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1); // bits 6-7 of the clock_seq_hi_and_reserved to 01
    s[8] = s[13] = s[18] = s[23] = "-";
    let uuid = s.join("");
    return uuid;
}

/**
 * 对目标字符串进行替换操作
 * @param inStr 要被替换的字符
 * @param replaceStr 想要替换成的字符
 * @param targetStr 要被操作的原始字符
 * @returns {string|*}
 */
const replaceStr = (inStr, replaceStr, targetStr) =>{
   // str.replace(/需要替换的字符串/g，'新字符串')
    if (targetStr.length == 0) return ''
    // 需要替换的字符正则形式
    const reg = /-/g
    // 替换后
    const result = targetStr.replace(reg, replaceStr)
    return result
}

/**
 * 将字符串md5加密
 * @param str
 */
const md5Str = (str) => {
    return md5(str);
}

/**
 * 数据保存到本地
 * @param key
 * @param valueObject
 */
const setLocalStorage = (key, valueObject) => {
    let localStorage = window.localStorage;
    if (typeof valueObject === 'string' || typeof valueObject === 'number') {
        // 存值为json
        localStorage.setItem(key, valueObject);
    } else if (typeof valueObject === 'boolean') {
        if (valueObject) {
            localStorage.setItem(key, 'true');
        } else {
            localStorage.setItem(key, 'false');
        }
    } else if (valueObject === null || typeof valueObject === 'undefined') {
        localStorage.removeItem(key);
        window.console.log('LocalStorage:暂不支持存储:key=' + key + '\nvalueObject=' + JSON.stringify(valueObject));
    } else if (typeof valueObject === 'object') {
        localStorage.setItem(key, JSON.stringify(valueObject));
    } else {
        localStorage.removeItem(key);
        window.console.log('LocalStorage:暂不支持存储:key=' + key + '\nvalueObject=' + JSON.stringify(valueObject));
    }
};

/**
 * 设置localstorage - 带有效时长
 * @param key 设置缓存的键名
 * @param value 设置缓存值过期时间(秒)
 * */
export function setStorage(key, value, Expires) {
    const storage = window.localStorage;
    if (!storage) {
        alert('浏览器不支持localstorage');
        return false;
    } else {
        // 当前时间戳 毫秒
        const nowTime = new Date().getTime();
        // 设置过期时间
        const dataExpires = Expires ? nowTime + Expires * 1000 : '';
        storage.setItem(key, JSON.stringify({ result: value, expires: dataExpires }));
    }
}

/**
 * 获取localstorage - 可能要比对有效时长 注意：返回的为一个对象
 * @param key 获取缓存的键名
 * */
export function getStorage(key) {
    const storage = window.localStorage;
    if (!storage) {
        alert('浏览器不支持localstorage');
        return false;
    } else {
        const result = JSON.parse(storage.getItem(key));
        if (!result) {
            // 缓存未设置
            return { result: null, expires: '' };
        }
        if (result.expires !== '' && result.expires < Date.now()) {
            // 设置了过期时间 并且 时间过期
            return { result: null, expires: '' };
        } else {
            // 还在有效时间内
            return result;
        }
    }
}

/**
 * 根据key获取对象
 * @param {string}key
 * @return {any}
 */
const getLocalStorage = (key) => {
    let localStorage = window.localStorage;
    let valueObject = localStorage.getItem(key);
    if (typeof valueObject === 'string') {
        // 尝试能否转成对象
        if (isJSONString(valueObject)) {
            let parseObject = JSON.parse(valueObject);
            if (typeof parseObject === 'object') {
                // 为对象
                return parseObject;
            }
        }

        // 不能转化为对象
        return valueObject;
    } else {
        window.console.log('localStorage:无key=' + key + '值可取');
        return '';
    }
};

/**
 * 判断字符是否是json字符串
 * @param str
 * @return {boolean}
 */
const isJSONString = (str) => {
    if (typeof str === 'string') {
        try {
            const obj = JSON.parse(str);
            if (str.indexOf('{') > -1 && obj) {
                return true;
            } else {
                return false;
            }
        } catch (e) {
            return false;
        }
    }
    return false;
};

/**
 * 字符串安全处理
 */
const nullStr = (str) => {
  if (!str || typeof str == 'undefined') {
      return ""
  }
  return str
}

/**
 * 获取设备宽
 * @returns {number}
 */
const getAppWidth = () => {
    return document.documentElement.clientWidth
}

/**
 * 获取设备高度
 * @returns {number}
 */
const getAppHeight = () => {
  return document.documentElement.clientHeight
}

/**
 * 获取设备宽*高字符
 * @returns {string}
 */
const getDpi = () => {
    const appW = getAppWidth()
    const appH = getAppHeight()
    const dpi = `${appW}*${appH}`
    return dpi
}

/**
 * 根据时间格式获取当前时间的描述
 * @param formatter
 */
export function getNowTimeStrWithFormatter(formatter) {
    if (!formatter || formatter.length == 0) {
        formatter = 'yyyy-MM-dd HH:mm:ss'
    }
    let time = new Date()
    return getTimeWithFormatter(time, formatter)
}

/**
 * 获取指定格式的时间
 * @param time 时间戳
 * @param formatter 日期格式 可以添加想要的格式
 * @returns {string}
 */
export function getTimeWithFormatter (time, formatter) {
    if (!time) return '--';
    if (!formatter) {
        formatter = 'yyyy-MM-dd HH:mm:ss'
    }
    const d = new Date(time);
    const year = d.getFullYear();
    // 月的索引从0开始 所以值需要 + 1
    const month = d.getMonth() + 1 < 10 ? '0' + (d.getMonth() + 1) : d.getMonth() + 1;
    const day = d.getDate() < 10 ? '0' + d.getDate() : d.getDate();
    const h = d.getHours() < 10 ? '0' + d.getHours() : d.getHours();
    const m = d.getMinutes() < 10 ? '0' + d.getMinutes() : d.getMinutes();
    const s = d.getSeconds() < 10 ? '0' + d.getSeconds() : d.getSeconds();

    let result = '';
    if (formatter === 'yyyy-MM-dd') {
        result = `${year}-${month}-${day}`;
    } else if (formatter === 'yyyy-MM-dd HH:mm:ss') {
        result = `${year}-${month}-${day} ${h}:${m}:${s}`;
    } else if (formatter === 'HH:mm:ss') {
        result = `${h}:${m}:${s}`;
    } else if (formatter === 'HH:mm') {
        result = `${h}:${m}`;
    } else {
        result = `${year}-${month}-${day}`;
    }
    return result;
};

/**
 * 根据时间字符串获取时间戳 若传空或不传则返回当前时间时间戳
 * @param str yyyy-MM-dd HH:mm:ss
 */
export function getTimestampByStr(str) {
    if (!str || str.length == 0) {
        let timestamp = new Date().getTime();
        return timestamp
    }
    let date = str;
    // if (str.length >= 19)
    // date = date.substring(0, 19);
    let timestamp = new Date(date).getTime();
    return timestamp
}

/**
 * 对目标名称的表单进行重置
 * @param refName 表单名字
 */
export function resetForm(refName) {
    if (this.$refs[refName]) {
        this.$refs[refName].resetFields();
    }
};

/**
 * 添加日期范围
 * @param params  请求参数集合对象
 * @param dateRange 日期范围
 * @param propName 指定时间参数后面部分 开始和结束前缀固定
 * @returns {*}
 */
export function addDateRange(params, dateRange, propName) {
    let search = params;
    search.params = typeof (search.params) === 'object' && search.params !== null && !Array.isArray(search.params) ? search.params : {};
    dateRange = Array.isArray(dateRange) ? dateRange : [];
    if (typeof (propName) === 'undefined') {
        search.params['beginTime'] = dateRange[0];
        search.params['endTime'] = dateRange[1];
    } else {
        search.params['begin' + propName] = dateRange[0];
        search.params['end' + propName] = dateRange[1];
    }
    return search;
}

/**
 * 是否为一个有效的字典对象 不仅是字典 还要有具体的键值对
 * @param obj
 */
const isValidObj = (obj) => {
    if (typeof obj === 'object' && Object.keys(obj).length > 0) {
        return true
    }
    return false
};

/**
 * 参数处理
 * @param {*} params  参数
 */
export function tansParams(params) {
    let result = ''
    for (const propName of Object.keys(params)) {
        const value = params[propName];
        var part = encodeURIComponent(propName) + "=";
        if (value !== null && typeof (value) !== "undefined") {
            if (typeof value === 'object') {
                for (const key of Object.keys(value)) {
                    if (value[key] !== null && typeof (value[key]) !== 'undefined') {
                        let params = propName + '[' + key + ']';
                        var subPart = encodeURIComponent(params) + "=";
                        result += subPart + encodeURIComponent(value[key]) + "&";
                    }
                }
            } else {
                result += part + encodeURIComponent(value) + "&";
            }
        }
    }
    return result
}

/**
 * 验证数据是否为blob格式
 * @param data
 * @returns {Promise<boolean>} async修饰 是当使用了awaits时
 */
export async function blobValidate(data) {
    try {
        const text = await data.text();
        JSON.parse(text);
        return false;
    } catch (error) {
        return true;
    }
}

/**
 * 测试阶段 是否需要打印信息
 * @returns {*}
 */
const needLog = () => {
    return false
}

/**
 * 获取不同平台图片 文件等资源基地址 （当下是快货运的）
 * @returns {string}
 */

export function getResourceBaseURL(platform) {
    return 'https://wlhyos-server-test.oss-cn-hangzhou.aliyuncs.com/'
}

/**
 * 将字符串的首字母大写处理
 * @param str
 * @returns {string}
 */
const upperCaseFirstStr = (str) => {
    let result = ''
    if (str && str.length > 0) {
        result = str[0].toUpperCase() + str.substr(1)
    }
    return result
}

/**
 * 根据url获取对应的Blob对象
 * @param url
 * @returns {Promise<unknown>}
 */
export function urlToBlob(url) {
    // 使用Promise对象返回Blob结果，以便在异步操作中使用。
    return new Promise((resolve, reject) => {
        fetch(url)
            // 使用response.blob()方法将响应转换为Blob对象
            .then(response => response.blob())
            .then(blob => {
                resolve(blob);
            })
            .catch(error => {
                reject(error);
            });
    });
}

/**
 * 使用a标签进行简单的文件下载（能指定文件下载名称 和插件file-saver方法表现一致）
 * @param fileUrl
 * @param fileName
 * @param fileType
 */
export function downloadFileByFileInfo(fileUrl, fileName, fileType) {
    let lastComponent = `${fileName}.${fileType}`;
    let a = document.createElement("a");
    // a.href = fileUrl;
    a.href = 'https://img0.baidu.com/it/u=3049998987,1866756846&fm=253&fmt=auto&app=138&f=JPEG?w=501&h=500';
    a.download = lastComponent;
    a.click();
    a.remove()
}

/**
 * Base64编码图像转化为Blob对象
 * @param dataUrl
 * @returns {*}
 */
export function base64ToBlob(dataUrl) {
    let arr = dataUrl.split(','),
        mime = arr[0].match(/:(.*?);/)[1],
        bstr = atob(arr[1]),
        n = bstr.length,
        u8arr = new Uint8Array(n);
    while (n--) {
        u8arr[n] = bstr.charCodeAt(n);
    }
    return new Blob([u8arr], { type: mime });
};

/**
 * 获取当前路由页面的scheme
 * @returns {string}
 */
const getCurrentScheme = () => {
    const scheme = window.location.protocol;
    return scheme;
}

// 判断是否在微信中查看
export const isWeChat = () => {
    const ua = navigator.userAgent.toLowerCase();
    if (/MicroMessenger/i.test(ua)) return true;
    else return false;
};


// 判断是否是iOS设备
export const isIos = () => {
    const ua = navigator.userAgent.toLowerCase();
    if (/(iPhone|iPad|iPod|iOS)/i.test(ua)) return true;
    else return false;
};

// 判断是否是QQ环境
export const isQQ = function() {
    const ua = navigator.userAgent.toLowerCase();
    if (ua.match(/\sQQ/i) !== null) return true;
    else return false;

};

// 判断是否是Android环境
export const isAndroid = function() {
    const ua = navigator.userAgent.toLowerCase();
    if (/Android/i.test(ua)) return true;
    else return false;
};

/**
 * 是否为手机端 true是
 * @returns {boolean}
 */
export const isMobileV2 = () => {
    let isMobile = isIos() || isAndroid()
    console.log('isMobile:', isMobile)
    return isMobile
}


/**
 * 导出util工具类
 * @type {{getDecode: *}}
 */
export const util = {
    getDecodeBase64,
    getEncodeBase64,
    getUuid,
    replaceStr,
    md5Str,
    setLocalStorage,
    isJSONString,
    getLocalStorage,
    nullStr,
    getAppWidth,
    getAppHeight,
    getDpi,
    isValidObj,
    needLog,
    upperCaseFirstStr,
    getCurrentScheme,
}

/**
 * 常规的方法btoa atob只适用于本页面内使用 不适用数据传输
 * 常规的encode方法虽然界面上转的是utf-8，但是实际上 传输存储 的时候格式还是utf-16，后台返回的是utf-8格式，用decode界面实际上转的是utf-16,转utf-8会出现中文乱码。
 * 也就是说上述的编码和解码，适用于页面本身编码解码，不适合传输用。
 */
